package cn.cdeden.knowledge.service.impl;

import cn.cdeden.common.core.utils.MapstructUtils;
import cn.cdeden.common.core.utils.page.TableDataInfo;
import cn.cdeden.common.mybatis.validator.QueryHelpMybatisPlus;
import cn.cdeden.knowledge.domain.SysCalendar;
import cn.cdeden.knowledge.domain.SysResource;
import cn.cdeden.knowledge.domain.dto.SysCalendarDto;
import cn.cdeden.knowledge.domain.dto.SysResourceDto;
import cn.cdeden.knowledge.domain.dto.SysResourceQueryParam;
import cn.cdeden.knowledge.mapper.SysResourceMapper;
import cn.cdeden.knowledge.service.SysResourceService;
import cn.cdeden.knowledge.utils.PageUtil;
import cn.cdeden.system.api.RemoteDeptService;
import cn.cdeden.system.api.domain.vo.RemoteDeptVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author guojunxu
* @date 2024-07-09
*/
@Service
@AllArgsConstructor
// @CacheConfig(cacheNames = SysResourceService.CACHE_KEY)
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class SysResourceServiceImpl extends ServiceImpl<SysResourceMapper, SysResource> implements SysResourceService {

    // private final RedisUtils redisUtils;
    private final SysResourceMapper sysResourceMapper;
    @DubboReference(check = false)
    private final RemoteDeptService remoteDeptService;
//    private final SysResourcePlanService sysResourcePlanService;
//    private final ProjectTaskService projectTaskService;

    @Override
    public TableDataInfo<SysResourceDto> queryAll(SysResourceQueryParam query, Pageable pageable) {
        IPage<SysResource> queryPage = PageUtil.toMybatisPage(pageable);
//        IPage<SysResource> page = sysResourceMapper.selectPage(queryPage, new QueryWrapper<SysResource>().like("resource_name", query.getResourceName()));
        IPage<SysResourceDto> page = sysResourceMapper.getPage(queryPage, query);
        return TableDataInfo.build(page);
    }

    @Override
    public List<SysResourceDto> queryAll(SysResourceQueryParam query){
        return MapstructUtils.convert(sysResourceMapper.selectList(QueryHelpMybatisPlus.getPredicate(query)), SysResourceDto.class);
    }

    @Override
    public SysResource getById(Long id) {
        return sysResourceMapper.selectById(id);
    }

    @Override
    // @Cacheable(key = "'id:' + #p0")
    public SysResourceDto findById(Long id) {
        return MapstructUtils.convert(getById(id), SysResourceDto.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insert(SysResourceDto resources) {
        SysResource entity = MapstructUtils.convert(resources, SysResource.class);
        return this.save(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateById(SysResourceDto resources){
        SysResource entity = MapstructUtils.convert(resources, SysResource.class);
        boolean ret = this.updateById(entity);
        // delCaches(resources.id);
        return ret;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteByIds(Set<Long> ids){
        // delCaches(ids);
        return this.removeByIds(ids);
    }

    @Override
    public List<SysCalendarDto> resourceFollowShow(List<Long> resourceIds, Date startDate, Date endDate) {
        LocalDateTime startDateTime = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        LocalDateTime endDateTime = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String startTime = startDateTime.format(dateTimeFormatter);
        String endTime = endDateTime.format(dateTimeFormatter);
        List<SysCalendar> sysCalendarList = getBaseMapper().resourceFollowShow(resourceIds, startTime, endTime);
        List<SysCalendarDto> sysCalendarDtos = MapstructUtils.convert(sysCalendarList, SysCalendarDto.class);
        //加入工时任务数据
//        List<SysResourcePlan> sysResourcePlanList = sysResourcePlanService.list(new QueryWrapper<SysResourcePlan>().eq("module_type", "pro").in("resource_id", resourceIds).between("resource_start_time", startTime, endTime).or().between("resource_end_time", startTime, endTime));
//        List<String> taskIdList = sysResourcePlanList.stream().map(SysResourcePlan::getTaskId).collect(Collectors.toList());
//        List<SysCalendarDto> myTaskSysCalendarDtoList = new ArrayList<>();
//        if (!taskIdList.isEmpty()) {
//            List<ProjectTask> projectTaskList = projectTaskService.list(new LambdaQueryWrapper<ProjectTask>().in(ProjectTask::getGuid, taskIdList));
//            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//            for (int i = 0; i < projectTaskList.size(); i++) {
//                SysCalendarDto sysCalendarDto = new SysCalendarDto();
//                sysCalendarDto.setLabel(projectTaskList.get(i).getTaskName());
//                sysCalendarDto.setContent(projectTaskList.get(i).getTaskRemark());
//                sysCalendarDto.setProjectId(projectTaskList.get(i).getProjectId());
//                sysCalendarDto.setCategory("task");
//                try {
//                    String myTaskStartDateTime = projectTaskList.get(i).getBeginTimeEn() + " 00:00:00";
//                    Date myTaskStartDate = dateFormat.parse(myTaskStartDateTime);
//                    sysCalendarDto.setStartDate(myTaskStartDate);
//
//                    String myTaskEndDateTime = projectTaskList.get(i).getEndTimeEn() + " 23:59:59";
//                    Date myTaskEndDate = dateFormat.parse(myTaskEndDateTime);
//                    sysCalendarDto.setEndDate(myTaskEndDate);
//
//                } catch (ParseException e) {
//                    e.printStackTrace();
//                }
//                sysCalendarDto.setMyTaskId(projectTaskList.get(i).getGuid());
//                myTaskSysCalendarDtoList.add(sysCalendarDto);
//            }
//        }
//        sysCalendarDtos.addAll(myTaskSysCalendarDtoList);
        sysCalendarDtos.forEach(v -> {
            if (v.getCategory() == null || v.getCategory().isEmpty()) {
                v.setCategory("calendar");
            }
        });
        return sysCalendarDtos;
    }

    @Override
    public Set<Long> getDepartmentAndSubDepartments(List<Long> deptIds) {
        Set<Long> departmentIds = new HashSet<>();
        deptIds.forEach(v -> {
            findSubDepartments(v, departmentIds);
        });
        return departmentIds;
    }

    private void findSubDepartments(Long deptId, Set<Long> departmentIds) {
        departmentIds.add(deptId);
        List<RemoteDeptVo> deptList = remoteDeptService.getByParentId(deptId);
        for (RemoteDeptVo dept : deptList) {
            departmentIds.add(dept.getDeptId());
            findSubDepartments(dept.getDeptId(), departmentIds);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteById(Long id){
        Set<Long> set = new HashSet<>(1);
        set.add(id);
        return this.deleteByIds(set);
    }

    /*
    private void delCaches(Long id) {
        redisUtils.delByKey(CACHE_KEY + "::id:", id);
    }

    private void delCaches(Set<Long> ids) {
        for (Long id: ids) {
            delCaches(id);
        }
    }*/

    /*
    @Override
    public void download(List<SysResourceDto> all, HttpServletResponse response) throws IOException {
      List<Map<String, Object>> list = new ArrayList<>();
      for (SysResourceDto sysResource : all) {
        Map<String,Object> map = new LinkedHashMap<>();
              map.put("资源名称", sysResource.getResourceName());
              map.put("资源描述", sysResource.getResourceDescribe());
              map.put("资源类型", sysResource.getResourceType());
              map.put("[默认1：启用 0：禁用]", sysResource.getResourceFlag());
              map.put("创建时间", sysResource.getCreateTime());
              map.put("创建人", sysResource.getCreateBy());
        list.add(map);
      }
      FileUtil.downloadExcel(list, response);
    }*/
}
